#!/bin/bash

# 日志轮转和监控告警设置脚本

set -e

# 配置
LOG_DIR="${LOG_DIR:-./logs}"
CONFIG_DIR="${CONFIG_DIR:-./config}"
PROMETHEUS_CONFIG="$CONFIG_DIR/prometheus"
GRAFANA_CONFIG="$CONFIG_DIR/grafana"
ALERTMANAGER_CONFIG="$CONFIG_DIR/alertmanager"

# 监控配置
PROMETHEUS_PORT="${PROMETHEUS_PORT:-9090}"
GRAFANA_PORT="${GRAFANA_PORT:-3000}"
ALERTMANAGER_PORT="${ALERTMANAGER_PORT:-9093}"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_debug() {
    echo -e "${BLUE}[DEBUG]${NC} $1"
}

# 检查命令是否存在
check_command() {
    if ! command -v $1 &> /dev/null; then
        log_error "Command '$1' not found"
        exit 1
    fi
}

# 创建配置目录
create_config_dirs() {
    log_info "Creating monitoring configuration directories..."
    
    mkdir -p "$PROMETHEUS_CONFIG"
    mkdir -p "$GRAFANA_CONFIG/provisioning/datasources"
    mkdir -p "$GRAFANA_CONFIG/provisioning/dashboards"
    mkdir -p "$ALERTMANAGER_CONFIG"
    mkdir -p "$ALERTMANAGER_CONFIG/templates"
    
    log_info "Configuration directories created"
}

# 创建logrotate配置
create_logrotate_config() {
    log_info "Creating logrotate configuration..."
    
    cat > "$CONFIG_DIR/logrotate.conf" << 'EOF'
# Logrotate configuration for offline-language-player

# Global options
compress
delaycompress
missingok
notifempty
create 0644 app app

# Application logs
$LOG_DIR/*.log {
    daily
    rotate 30
    maxsize 100M
    missingok
    notifempty
    compress
    delaycompress
    sharedscripts
    postrotate
        # Send USR1 signal to application to reopen log files
        if pgrep -f "uvicorn.*app.main:app" > /dev/null; then
            pkill -USR1 -f "uvicorn.*app.main:app" || true
        fi
    endscript
}

# Error logs
$LOG_DIR/*error.log {
    daily
    rotate 60
    maxsize 50M
    missingok
    notifempty
    compress
    delaycompress
}

# Access logs
$LOG_DIR/*access.log {
    daily
    rotate 30
    maxsize 200M
    missingok
    notifempty
    compress
    delaycompress
}

# Nginx logs
$LOG_DIR/nginx/*.log {
    daily
    rotate 14
    maxsize 500M
    missingok
    notifempty
    compress
    delaycompress
    sharedscripts
    postrotate
        # Reload Nginx
        if pgrep nginx > /dev/null; then
            nginx -s reload || true
        fi
    endscript
}
EOF
    
    log_info "Logrotate configuration created: $CONFIG_DIR/logrotate.conf"
}

# 创建systemd服务文件
create_systemd_services() {
    log_info "Creating systemd service files..."
    
    # Logrotate定时任务
    cat > "/tmp/logrotate.service" << 'EOF'
[Unit]
Description=Rotate application logs
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/logrotate /app/config/logrotate.conf
User=root
Group=root

[Install]
WantedBy=multi-user.target
EOF
    
    cat > "/tmp/logrotate.timer" << 'EOF'
[Unit]
Description=Rotate application logs daily
Requires=logrotate.service

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target
EOF
    
    log_info "Systemd service files created in /tmp/"
}

# 设置logrotate定时任务
setup_logrotate_cron() {
    log_info "Setting up logrotate cron job..."
    
    # 创建cron脚本
    cat > "$CONFIG_DIR/logrotate.sh" << EOF
#!/bin/bash
# Logrotate script for offline-language-player

/usr/sbin/logrotate $CONFIG_DIR/logrotate.conf
EOF
    
    chmod +x "$CONFIG_DIR/logrotate.sh"
    
    log_info "Logrotate script created: $CONFIG_DIR/logrotate.sh"
    
    # 添加到crontab（如果需要）
    log_warn "To enable daily log rotation, add to crontab:"
    log_warn "0 2 * * * $CONFIG_DIR/logrotate.sh"
}

# 创建Prometheus配置
create_prometheus_config() {
    log_info "Creating Prometheus configuration..."
    
    cat > "$PROMETHEUS_CONFIG/prometheus.yml" << EOF
global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  - "alert_rules.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - alertmanager:$ALERTMANAGER_PORT

scrape_configs:
  # Application metrics
  - job_name: 'offline-language-player'
    static_configs:
      - targets: ['app:8000']
    metrics_path: '/api/v1/metrics'
    scrape_interval: 15s
    scrape_timeout: 10s

  # Nginx metrics (if available)
  - job_name: 'nginx'
    static_configs:
      - targets: ['nginx:9113']
    scrape_interval: 30s

  # Redis metrics (if available)
  - job_name: 'redis'
    static_configs:
      - targets: ['redis:6379']
    scrape_interval: 30s

  # Node Exporter (if available)
  - job_name: 'node-exporter'
    static_configs:
      - targets: ['node-exporter:9100']
    scrape_interval: 30s

  # Prometheus itself
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:$PROMETHEUS_PORT']
    scrape_interval: 30s
EOF
    
    log_info "Prometheus configuration created: $PROMETHEUS_CONFIG/prometheus.yml"
}

# 创建告警规则
create_alert_rules() {
    log_info "Creating alert rules..."
    
    cat > "$PROMETHEUS_CONFIG/alert_rules.yml" << EOF
groups:
  - name: application.rules
    rules:
      # Application is down
      - alert: ApplicationDown
        expr: up{job="offline-language-player"} == 0
        for: 1m
        labels:
          severity: critical
          service: offline-language-player
        annotations:
          summary: "Application is down"
          description: "Application has been down for more than 1 minute"

      # High error rate
      - alert: HighErrorRate
        expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1
        for: 2m
        labels:
          severity: warning
          service: offline-language-player
        annotations:
          summary: "High error rate detected"
          description: "Error rate is {{ $value }} errors per second"

      # High memory usage
      - alert: HighMemoryUsage
        expr: (app_memory_usage_bytes / 1024 / 1024) > 1000
        for: 5m
        labels:
          severity: warning
          service: offline-language-player
        annotations:
          summary: "High memory usage"
          description: "Memory usage is {{ $value }}MB"

      # High CPU usage
      - alert: HighCpuUsage
        expr: app_cpu_usage_percent > 80
        for: 5m
        labels:
          severity: warning
          service: offline-language-player
        annotations:
          summary: "High CPU usage"
          description: "CPU usage is {{ $value }}%"

      # Database connection issues
      - alert: DatabaseConnectionIssues
        expr: app_database_connections_failed_total > 10
        for: 1m
        labels:
          severity: critical
          service: offline-language-player
        annotations:
          summary: "Database connection issues"
          description: "Database connection failures: {{ $value }}"

      # Redis connection issues
      - alert: RedisConnectionIssues
        expr: app_redis_connections_failed_total > 5
        for: 1m
        labels:
          severity: warning
          service: offline-language-player
        annotations:
          summary: "Redis connection issues"
          description: "Redis connection failures: {{ $value }}"

  - name: system.rules
    rules:
      # High disk usage
      - alert: HighDiskUsage
        expr: (node_filesystem_size_bytes - node_filesystem_avail_bytes) / node_filesystem_size_bytes * 100 > 85
        for: 5m
        labels:
          severity: warning
          service: system
        annotations:
          summary: "High disk usage"
          description: "Disk usage is {{ $value }}%"

      # High memory usage on node
      - alert: NodeHighMemoryUsage
        expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 90
        for: 5m
        labels:
          severity: critical
          service: system
        annotations:
          summary: "Node high memory usage"
          description: "Node memory usage is {{ $value }}%"
EOF
    
    log_info "Alert rules created: $PROMETHEUS_CONFIG/alert_rules.yml"
}

# 创建Alertmanager配置
create_alertmanager_config() {
    log_info "Creating Alertmanager configuration..."
    
    cat > "$ALERTMANAGER_CONFIG/alertmanager.yml" << EOF
global:
  smtp_smarthost: 'localhost:587'
  smtp_from: 'alerts@example.com'
  smtp_auth_username: 'alerts@example.com'
  smtp_auth_password: 'your-email-password'

route:
  group_by: ['alertname', 'service']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: 'default'
  routes:
    - match:
        severity: critical
      receiver: 'critical'
    - match:
        severity: warning
      receiver: 'warning'

receivers:
  - name: 'default'
    email_configs:
      - to: 'admin@example.com'
        subject: '[OFFLINE-LANGUAGE-PLAYER] {{ .GroupLabels.alertname }}'
        body: |
          {{ range .Alerts }}
          Alert: {{ .Annotations.summary }}
          Description: {{ .Annotations.description }}
          Labels: {{ range .Labels.SortedPairs }}{{ .Name }}={{ .Value }} {{ end }}
          {{ end }}

  - name: 'critical'
    email_configs:
      - to: 'critical@example.com'
        subject: '[CRITICAL] OFFLINE-LANGUAGE-PLAYER {{ .GroupLabels.alertname }}'
        body: |
          CRITICAL ALERT!
          
          {{ range .Alerts }}
          Alert: {{ .Annotations.summary }}
          Description: {{ .Annotations.description }}
          Labels: {{ range .Labels.SortedPairs }}{{ .Name }}={{ .Value }} {{ end }}
          {{ end }}
    webhook_configs:
      - url: 'http://localhost:8080/webhooks/critical'
        send_resolved: true

  - name: 'warning'
    email_configs:
      - to: 'warnings@example.com'
        subject: '[WARNING] OFFLINE-LANGUAGE-PLAYER {{ .GroupLabels.alertname }}'
        body: |
          Warning Alert!
          
          {{ range .Alerts }}
          Alert: {{ .Annotations.summary }}
          Description: {{ .Annotations.description }}
          Labels: {{ range .Labels.SortedPairs }}{{ .Name }}={{ .Value }} {{ end }}
          {{ end }}

inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'service']
EOF
    
    log_info "Alertmanager configuration created: $ALERTMANAGER_CONFIG/alertmanager.yml"
}

# 创建Grafana数据源配置
create_grafana_datasources() {
    log_info "Creating Grafana datasources configuration..."
    
    cat > "$GRAFANA_CONFIG/provisioning/datasources/prometheus.yml" << EOF
apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:$PROMETHEUS_PORT
    isDefault: true
    editable: true
    jsonData:
      timeInterval: "5s"
      queryTimeout: "60s"
      httpMethod: POST
EOF
    
    log_info "Grafana datasource configuration created"
}

# 创建Grafana仪表板配置
create_grafana_dashboards() {
    log_info "Creating Grafana dashboards configuration..."
    
    cat > "$GRAFANA_CONFIG/provisioning/dashboards/dashboards.yml" << EOF
apiVersion: 1

providers:
  - name: 'default'
    orgId: 1
    folder: ''
    type: file
    disableDeletion: false
    updateIntervalSeconds: 10
    allowUiUpdates: true
    options:
      path: /etc/grafana/provisioning/dashboards
EOF
    
    # 创建基础仪表板
    cat > "$GRAFANA_CONFIG/provisioning/dashboards/overview-dashboard.json" << 'EOF'
{
  "dashboard": {
    "id": null,
    "title": "Offline Language Player Overview",
    "tags": ["offline-language-player"],
    "timezone": "browser",
    "panels": [
      {
        "id": 1,
        "title": "Application Status",
        "type": "stat",
        "targets": [
          {
            "expr": "up{job=\"offline-language-player\"}",
            "legendFormat": "{{ instance }}"
          }
        ],
        "fieldConfig": {
          "defaults": {
            "mappings": [
              {"options": {"0": {"text": "DOWN", "color": "red"}}, "type": "value"},
              {"options": {"1": {"text": "UP", "color": "green"}}, "type": "value"}
            ]
          }
        },
        "gridPos": {"h": 8, "w": 12, "x": 0, "y": 0}
      },
      {
        "id": 2,
        "title": "Request Rate",
        "type": "graph",
        "targets": [
          {
            "expr": "rate(http_requests_total[5m])",
            "legendFormat": "{{ method }} {{ status }}"
          }
        ],
        "yAxes": [{"label": "Requests/sec"}],
        "gridPos": {"h": 8, "w": 12, "x": 12, "y": 0}
      },
      {
        "id": 3,
        "title": "Memory Usage",
        "type": "graph",
        "targets": [
          {
            "expr": "app_memory_usage_bytes / 1024 / 1024",
            "legendFormat": "Memory (MB)"
          }
        ],
        "yAxes": [{"label": "Memory (MB)"}],
        "gridPos": {"h": 8, "w": 12, "x": 0, "y": 8}
      },
      {
        "id": 4,
        "title": "CPU Usage",
        "type": "graph",
        "targets": [
          {
            "expr": "app_cpu_usage_percent",
            "legendFormat": "CPU (%)"
          }
        ],
        "yAxes": [{"label": "CPU (%)"}],
        "gridPos": {"h": 8, "w": 12, "x": 12, "y": 8}
      }
    ],
    "time": {"from": "now-1h", "to": "now"},
    "refresh": "5s"
  }
}
EOF
    
    log_info "Grafana dashboard configuration created"
}

# 创建监控脚本
create_monitoring_scripts() {
    log_info "Creating monitoring scripts..."
    
    # 健康检查脚本
    cat > "$CONFIG_DIR/health-monitor.sh" << 'EOF'
#!/bin/bash

# 健康监控脚本

LOG_FILE="./logs/health-monitor.log"
ALERT_THRESHOLD=3
CURRENT_FAILURES=0

check_health() {
    response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/api/v1/health)
    
    if [ "$response" = "200" ]; then
        echo "$(date): Health check PASSED" >> "$LOG_FILE"
        CURRENT_FAILURES=0
    else
        echo "$(date): Health check FAILED (HTTP $response)" >> "$LOG_FILE"
        CURRENT_FAILURES=$((CURRENT_FAILURES + 1))
        
        if [ $CURRENT_FAILURES -ge $ALERT_THRESHOLD ]; then
            echo "$(date): ALERT: Application health check failed $CURRENT_FAILURES times" >> "$LOG_FILE"
            # 发送告警（这里可以添加邮件、Slack等通知）
        fi
    fi
}

while true; do
    check_health
    sleep 30
done
EOF
    
    # 性能监控脚本
    cat > "$CONFIG_DIR/perf-monitor.sh" << 'EOF'
#!/bin/bash

# 性能监控脚本

LOG_FILE="./logs/perf-monitor.log"

collect_metrics() {
    timestamp=$(date -Iseconds)
    
    # 内存使用
    memory_usage=$(free | grep Mem | awk '{printf "%.2f", $3/$2 * 100.0}')
    
    # CPU使用率
    cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')
    
    # 磁盘使用
    disk_usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
    
    echo "$timestamp,cpu=$cpu_usage,memory=$memory_usage,disk=$disk_usage" >> "$LOG_FILE"
}

while true; do
    collect_metrics
    sleep 60
done
EOF
    
    chmod +x "$CONFIG_DIR/health-monitor.sh"
    chmod +x "$CONFIG_DIR/perf-monitor.sh"
    
    log_info "Monitoring scripts created"
}

# 创建启动脚本
create_monitoring_start_script() {
    log_info "Creating monitoring startup script..."
    
    cat > "$CONFIG_DIR/start-monitoring.sh" << 'EOF'
#!/bin/bash

# 监控服务启动脚本

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_DIR="${LOG_DIR:-./logs}"

# 创建日志目录
mkdir -p "$LOG_DIR"

# 启动健康监控
echo "Starting health monitor..."
nohup "$SCRIPT_DIR/health-monitor.sh" > "$LOG_DIR/health-monitor.out" 2>&1 &

# 启动性能监控
echo "Starting performance monitor..."
nohup "$SCRIPT_DIR/perf-monitor.sh" > "$LOG_DIR/perf-monitor.out" 2>&1 &

echo "Monitoring services started"
EOF
    
    # 停止脚本
    cat > "$CONFIG_DIR/stop-monitoring.sh" << 'EOF'
#!/bin/bash

# 监控服务停止脚本

echo "Stopping health monitor..."
pkill -f "health-monitor.sh" || true

echo "Stopping performance monitor..."
pkill -f "perf-monitor.sh" || true

echo "Monitoring services stopped"
EOF
    
    chmod +x "$CONFIG_DIR/start-monitoring.sh"
    chmod +x "$CONFIG_DIR/stop-monitoring.sh"
    
    log_info "Monitoring startup scripts created"
}

# 创建systemd服务文件
create_monitoring_systemd() {
    log_info "Creating systemd services for monitoring..."
    
    cat > "/tmp/health-monitor.service" << 'EOF'
[Unit]
Description=Health Monitor Service
After=network.target

[Service]
Type=simple
User=app
WorkingDirectory=/app
ExecStart=/app/config/health-monitor.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF
    
    cat > "/tmp/perf-monitor.service" << 'EOF'
[Unit]
Description=Performance Monitor Service
After=network.target

[Service]
Type=simple
User=app
WorkingDirectory=/app
ExecStart=/app/config/perf-monitor.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF
    
    log_info "Systemd service files created in /tmp/"
}

# 测试配置
test_configurations() {
    log_info "Testing configurations..."
    
    # 测试logrotate配置
    if command -v logrotate &> /dev/null; then
        log_info "Testing logrotate configuration..."
        logrotate --debug "$CONFIG_DIR/logrotate.conf" || log_warn "Logrotate configuration test failed"
    fi
    
    # 测试Prometheus配置
    if [ -f "$PROMETHEUS_CONFIG/prometheus.yml" ]; then
        log_info "Prometheus configuration exists"
    fi
    
    # 测试Alertmanager配置
    if [ -f "$ALERTMANAGER_CONFIG/alertmanager.yml" ]; then
        log_info "Alertmanager configuration exists"
    fi
    
    log_info "Configuration tests completed"
}

# 显示安装信息
show_install_info() {
    log_info "Monitoring setup completed!"
    echo ""
    echo "Configuration files created:"
    echo "  Logrotate: $CONFIG_DIR/logrotate.conf"
    echo "  Prometheus: $PROMETHEUS_CONFIG/prometheus.yml"
    echo "  Alertmanager: $ALERTMANAGER_CONFIG/alertmanager.yml"
    echo "  Grafana: $GRAFANA_CONFIG/provisioning/"
    echo ""
    echo "Monitoring scripts:"
    echo "  Health Monitor: $CONFIG_DIR/health-monitor.sh"
    echo "  Performance Monitor: $CONFIG_DIR/perf-monitor.sh"
    echo ""
    echo "Service control:"
    echo "  Start: $CONFIG_DIR/start-monitoring.sh"
    echo "  Stop: $CONFIG_DIR/stop-monitoring.sh"
    echo ""
    echo "Next steps:"
    echo "1. Copy systemd service files from /tmp/ to /etc/systemd/system/"
    echo "2. Enable and start services: systemctl enable --now logrotate.timer"
    echo "3. Set up cron job for logrotate: 0 2 * * * $CONFIG_DIR/logrotate.sh"
    echo "4. Configure email settings in Alertmanager"
    echo "5. Start monitoring services: $CONFIG_DIR/start-monitoring.sh"
}

# 显示帮助信息
show_help() {
    echo "Monitoring Setup Script"
    echo ""
    echo "Usage: $0 [OPTIONS]"
    echo ""
    echo "Options:"
    echo "  --logrotate-only      Setup only logrotate configuration"
    echo "  --prometheus-only     Setup only Prometheus configuration"
    echo "  --grafana-only        Setup only Grafana configuration"
    echo "  --alertmanager-only   Setup only Alertmanager configuration"
    echo "  --test-only           Test existing configurations"
    echo "  --help                Show this help message"
    echo ""
    echo "Environment Variables:"
    echo "  LOG_DIR                Log directory (default: ./logs)"
    echo "  CONFIG_DIR             Configuration directory (default: ./config)"
    echo "  PROMETHEUS_PORT        Prometheus port (default: 9090)"
    echo "  GRAFANA_PORT           Grafana port (default: 3000)"
    echo "  ALERTMANAGER_PORT      Alertmanager port (default: 9093)"
}

# 主函数
main() {
    local action=""
    
    # 解析命令行参数
    while [[ $# -gt 0 ]]; do
        case $1 in
            --logrotate-only)
                action="logrotate"
                shift
                ;;
            --prometheus-only)
                action="prometheus"
                shift
                ;;
            --grafana-only)
                action="grafana"
                shift
                ;;
            --alertmanager-only)
                action="alertmanager"
                shift
                ;;
            --test-only)
                action="test"
                shift
                ;;
            --help)
                show_help
                exit 0
                ;;
            *)
                log_error "Unknown option: $1"
                show_help
                exit 1
                ;;
        esac
    done
    
    # 创建必要目录
    mkdir -p "$CONFIG_DIR" "$LOG_DIR"
    
    # 执行相应操作
    case $action in
        "logrotate")
            create_logrotate_config
            setup_logrotate_cron
            ;;
        "prometheus")
            create_config_dirs
            create_prometheus_config
            create_alert_rules
            ;;
        "grafana")
            create_config_dirs
            create_grafana_datasources
            create_grafana_dashboards
            ;;
        "alertmanager")
            create_config_dirs
            create_alertmanager_config
            ;;
        "test")
            test_configurations
            ;;
        "")
            # 完整设置
            create_config_dirs
            create_logrotate_config
            setup_logrotate_cron
            create_systemd_services
            create_prometheus_config
            create_alert_rules
            create_alertmanager_config
            create_grafana_datasources
            create_grafana_dashboards
            create_monitoring_scripts
            create_monitoring_systemd
            create_monitoring_start_script
            test_configurations
            show_install_info
            ;;
    esac
}

# 运行主函数
main "$@"
